home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PD Collection CD 1
/
PD Collection CD 1.iso
/
programer2
/
euclidlib
/
c
/
function
< prev
next >
Wrap
Text File
|
1992-04-19
|
3KB
|
90 lines
/**** function.c ****/
/* By Paul Field
* See !ReadMe file for distribution/modification restrictions
*/
#include "function.h"
#include <float.h>
#include <stdio.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
static os_error memerr = { 0, "Not enough memory - increase wimpslot." };
/* Points on the graph are (X,Y,f(X,Y))
*/
os_error *function_makegraph(euclid_header *h, graphdata *g, euclid_mesh **mesh)
{ double *results, *r;
double minz,maxz; /* Maximum and minimum of the function */
double rangex,rangey,rangez;
double maxrange;
double scale;
double dy,dx; /* Change in function variables per square */
double fx,fy; /* Function variables */
int ax,ay; /* 'results' array indices */
os_error *e;
results = malloc((g->subdivisions+1)*(g->subdivisions+1)*sizeof(double));
if (results == NULL)
{ return(&memerr);
}
rangex = g->maxx-g->minx;
rangey = g->maxy-g->miny;
dx = rangex/g->subdivisions;
dy = rangey/g->subdivisions;
minz = DBL_MAX;
maxz = DBL_MIN;
r = results;
/* I'm using ax and ay because there may be rounding errors */
/* and other problems with fx and fy if dx and dy are small. */
for (ax = 0, fx = g->minx; ax <= g->subdivisions; ax++, fx += dx)
{ for (ay = 0, fy = g->miny; ay <= g->subdivisions; ay++, fy += dx)
{ *r = g->f(fx,fy);
maxz = max(*r,maxz);
minz = min(*r,minz);
r++;
}
}
rangez = maxz-minz;
maxrange = max(rangex, rangey);
maxrange = max(maxrange, rangez);
scale = g->realsize/maxrange;
if ((e = euclid_create(g->subdivisions+1, h, eid_mesh, mesh)) == NULL)
{ euclid_setname((*mesh)->name, g->name);
r = results;
for (ax = 0, fx = g->minx; ax <= g->subdivisions && !e; ax++, fx += dx)
{ euclid_vane *v;
if ((e = euclid_create(g->subdivisions+1, h, eid_vane, &v)) == NULL)
{ (*mesh)->var[ax].colour.c.abscolour = euclid_makecolour(0x80u,0,0,0);
(*mesh)->var[ax].vane = v;
for (ay = 0, fy = g->miny; ay <= g->subdivisions; ay++, fy += dx)
{ struct euclid_vanevar *vv;
vv = &v->var[ay];
vv->colour1.c.abscolour = euclid_makecolour(0x80u,0xff,0xff,0xff);
vv->colour2.c.abscolour = euclid_makecolour(0x80u,0xff,0xff,0xff);
vv->point.x = (int)((fx-g->minx-rangex/2)*scale+0.5);
vv->point.y = (int)((fy-g->miny-rangey/2)*scale+0.5);
vv->point.z = (int)((*r++)*scale+0.5);
}
}
}
if (e)
{ for (ax--; ax >= 0; ax--)
{ euclid_destroy(h, (*mesh)->var[ax].vane);
}
euclid_destroy(h, *mesh);
}
}
g->scale = scale;
free(results);
return(e);
}